package cn.me.alphamq.nameserver.config.cluster;

import cn.me.alphamq.common.util.PropertiesUtil;
import cn.me.alphamq.nameserver.enumeration.ReplicationRoleEnum;

import java.util.Properties;

/**
 * 链式复制的配置类
 *
 * @author f
 */
public class ChainReplicationProperties {

    /**
     * 下一个节点的 ip + 端口，尾节点没有，非尾节点有
     */
    private String nextNode;

    /**
     * 本节点在链式复制中扮演的角色
     *
     * @see ReplicationRoleEnum
     */
    private final ReplicationRoleEnum role;

    /**
     * 本节点向外开放的端口
     */
    private final Integer port;

    public ChainReplicationProperties(ReplicationRoleEnum role, Integer port) {
        this.role = role;
        this.port = port;
    }

    public ChainReplicationProperties(String nextNode, ReplicationRoleEnum role, Integer port) {
        this.nextNode = nextNode;
        this.role = role;
        this.port = port;
    }

    /**
     * 根据 properties 加载一个链式复制配置的对象
     *
     * @param properties 配置对象
     * @return 填充配置的对象
     */
    public static ChainReplicationProperties load(Properties properties) {
        ReplicationRoleEnum replicationRoleEnum = ReplicationRoleEnum.of(
                PropertiesUtil.getNotNullProperty(properties, "nameserver.replication.chain.role")
        );
        if (ReplicationRoleEnum.TAIL == replicationRoleEnum) {
            // 如果是尾节点，则没有 port 参数
            return new ChainReplicationProperties(
                    replicationRoleEnum,
                    PropertiesUtil.getIntProperty(properties, "nameserver.replication.chain.port")
            );
        } else {
            // 如果是非尾节点，则有 port 参数
            return new ChainReplicationProperties(
                    PropertiesUtil.getNotNullProperty(properties, "nameserver.replication.chain.next.node"),
                    replicationRoleEnum,
                    PropertiesUtil.getIntProperty(properties, "nameserver.replication.chain.port")
            );
        }
    }

    public String getNextNode() {
        return nextNode;
    }

    public ReplicationRoleEnum getRole() {
        return role;
    }

    public Integer getPort() {
        return port;
    }
}
